package com.zodiac.alioth.web.controller;

import com.alibaba.fastjson.JSON;
import com.zodiac.alioth.common.annotation.NotLogParams;
import com.zodiac.alioth.common.annotation.NotLogResults;
import com.zodiac.alioth.common.constants.CoreConst;
import com.zodiac.alioth.common.constants.RedisKeyPrefixConst;
import com.zodiac.alioth.common.encrypt.MD5Util;
import com.zodiac.alioth.common.model.form.LoginForm;
import com.zodiac.alioth.common.model.vo.ApiResponse;
import com.zodiac.alioth.common.util.MD5;
import com.zodiac.alioth.common.util.UUIDUtil;
import com.zodiac.alioth.service.redis.RedisService;
import com.zodiac.alioth.web.security.LoginContextHelper;
import com.zodiac.alioth.web.security.auth.AuthUser;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;
import java.io.UnsupportedEncodingException;
import java.security.NoSuchAlgorithmException;
import java.util.Objects;
import java.util.concurrent.TimeUnit;

/**
 * *****获取token测试用*****
 *
 * @author insight
 */
@Slf4j
@RestController
@RequestMapping(value = "/")
public class LoginController {

    @Resource
    private RedisService redisService;

    /**
     * token有效时长，默认7天
     */
    @Value("${token.valid.duration:604800}")
    private Long validDuration;

    /**
     * 跳转登录页面
     *
     * @param request
     * @return
     */
    @RequestMapping(value = "login", method = RequestMethod.GET)
    public String login(HttpServletRequest request) {
        AuthUser loginUser = LoginContextHelper.getLoginUser();
        String userName = loginUser.getUserName();
        return "must use post to login, userName=" + userName;
    }

    @RequestMapping(value = "/test/login", method = RequestMethod.GET)
    public String test(HttpServletRequest request) {
        AuthUser loginUser = LoginContextHelper.getLoginUser();
        String userName = loginUser.getUserName();
        log.info("/test/login success, authUser={}", JSON.toJSONString(loginUser));
        return "must use post to login, userName=" + userName;
    }

//    @NotLogParams
//    @NotLogResults
    @RequestMapping(value = "login", method = RequestMethod.POST)
    public ApiResponse<String> doLogin(HttpServletRequest request, HttpServletResponse httpServletResponse,
                                       @Valid @RequestBody LoginForm loginForm, BindingResult bindingResult) {
        if (bindingResult.hasErrors()) {
            return ApiResponse.getFailureResult(9999, "params error");
        }
        // 1。校验登录账号密码是否正确
        boolean passVerifyBool = MD5Util.verifyPassword(loginForm.getLoginName(), loginForm.getPassword(), "88f16bf74b9a83358f40a41f08d17ae43386155b3163de23");
        if (!passVerifyBool) {
            return ApiResponse.getFailureResult(9999, "password error");
        }

        AuthUser authUser = null;
        long now = System.currentTimeMillis();
        long expireTime = now + validDuration * 1000;

        String oldToken = request.getHeader(CoreConst.HEADER_X_TOKE);
        long expire = request.getDateHeader(CoreConst.HEADER_X_TOKEN_EXPIRE);
        if (StringUtils.isNotEmpty(oldToken) && expire > System.currentTimeMillis()) {
            authUser = redisService.get(RedisKeyPrefixConst.X_TOKEN_PREFIX + oldToken);
            if (Objects.nonNull(authUser)) {
                authUser.setTokenCreateTime(now);
                authUser.setTokenExpireTime(expireTime);
                redisService.del(RedisKeyPrefixConst.X_TOKEN_PREFIX + oldToken);
            }
        }

        if (Objects.isNull(authUser)) {
            authUser = new AuthUser();
            authUser.setUserId("00001");
            authUser.setUserName("admin");
            authUser.setLoginName(loginForm.getLoginName());
            authUser.setMobile("xxx");
            authUser.setRoles(new String[]{""});
            authUser.setTokenCreateTime(now);
            authUser.setTokenExpireTime(expireTime);
        }

        String token;
        try {
            token = MD5.md5Hex(JSON.toJSONString(authUser));
        } catch (NoSuchAlgorithmException | UnsupportedEncodingException e) {
            log.error("generate token error, authUser={}", JSON.toJSONString(authUser), e);
            token = UUIDUtil.uuid();
        }
        authUser.setXToken(token);

        redisService.set(RedisKeyPrefixConst.X_TOKEN_PREFIX + token, authUser, validDuration, TimeUnit.SECONDS);

        httpServletResponse.setHeader(CoreConst.HEADER_X_TOKE, token);
        httpServletResponse.setDateHeader(CoreConst.HEADER_X_TOKEN_EXPIRE, expireTime);

        //记录登陆日志
        return ApiResponse.getSuccessResult(token + " " + expireTime);
    }

    @RequestMapping(value = "logout")
    public ApiResponse<String> doLogout(HttpServletRequest request, HttpServletResponse httpServletResponse) {
        httpServletResponse.setHeader(CoreConst.HEADER_X_TOKE, null);
        httpServletResponse.setDateHeader(CoreConst.HEADER_X_TOKEN_EXPIRE, -1);

        String token = request.getHeader(CoreConst.HEADER_X_TOKE);
        redisService.del(RedisKeyPrefixConst.X_TOKEN_PREFIX + token);
        log.info("logout del token={}", token);
        return ApiResponse.getSuccessResult("logout success");
    }


}
